/*********************************************************
*Copyright (c) 2015 zhongsx. All Rights in Pw 
*@des: 环型缓冲区 
*@name: CircleBuffer.cpp
*@author: zhongsx
*@time: 2015-03-07
********************************************************/

#include "CircleBuffer.h"

/*
 * 实现环形缓冲区
 */
CircleBuffer::CircleBuffer(int MaxSize):max_size(MaxSize)
{
    buffer_ = new uint8_t[max_size];
    memset(buffer_, 0, max_size);
    read = write  = 0;
}
 
CircleBuffer::~CircleBuffer()
{
    delete []buffer_;
    read = write = 0;
}
 
//获取未读数据的size
int CircleBuffer::cont()
{
    boost::recursive_mutex::scoped_lock lock(mutex_); 

    int unread = (write > read) ? (write - read) : 
                    ((max_size - read) + write);
    return unread;
}

//获取还能写的空间大小
int CircleBuffer::emptysize()
{
    boost::recursive_mutex::scoped_lock lock(mutex_); 
    int unwrite = (write > read) ? ((max_size - write) + read) : (read - write);
    return unwrite;
}

int CircleBuffer::write_data(uint8_t* elem, int size)
{
    boost::recursive_mutex::scoped_lock lock(mutex_); 
    int _size = emptysize();
    if (_size == 0){
        return 0;
    }

    size = (_size > size) ? size : (size - _size);
    //写入数据
    if (write > read )
    {
        if ((max_size - write) > size ){
            //直接写入数据
            memcpy(buffer_ + write, elem, size);
            write += size;
        }
        else{
            //分部分一部分写到尾, 一部分写到头
            int tail_size = max_size - write;
            int head_size = size - tail_size;
            memcpy(buffer_ + write, elem, tail_size);
            memcpy(buffer_ , (elem + tail_size), head_size);
            write = head_size;
        }
    }
    else{
        memcpy(buffer_ + write, elem, size);
        write += size;
    }

	return size;
}

//当type == 0 时 实际读取rsize个字节 计数
//type != 0 时 预先读取rsize个字节 不计数
int CircleBuffer::read_data(uint8_t* elem, int rsize, int msize, int type)
{
	boost::recursive_mutex::scoped_lock lock(mutex_); 
    int size_ = cont();
    if (rsize > size_){
        return 0;
    }
    //检查数据是否
    if (rsize > cont()){
        return 0;
    }
    //memcpy(void *dest, const void *src, size_t n);
    if (write > read){
        memcpy(elem, buffer_ + read, rsize);
		if (type == 0){
		    read += rsize;
		}
    }
    else{
        int tail_size = max_size - read;
        if (tail_size > rsize){
            memcpy(elem, buffer_ + read, rsize);
			if (type == 0){
				read += rsize;
			}
        }
        else{
            memcpy(elem, buffer_ + read, tail_size);
            memcpy(elem + tail_size, buffer_, (rsize - tail_size));
			if (type == 0){
				read = rsize - tail_size;
			}
        }
    }
    return rsize;
}

void CircleBuffer::clear()
{
    boost::recursive_mutex::scoped_lock lock(mutex_); 
    write = read = 0;
}